#include <iostream>

using namespace std;


// 卷积操作
void finke(float *input, float *output, int m, int n, int kernel_size, int padding, int stride, float *kernel) {
    int o1 = (int)((m - kernel_size + 2 * padding) / stride) + 1;
    int o2 = (int)((n - kernel_size + 2 * padding) / stride) + 1;

    int p1 = 0;
    int p2 = 0; // 卷积起始坐标
    for (int i = 0; i < o1; i++) {
        for (int j = 0; j < o2; j++) {
            // 卷积操作
            int row = 0;
            int col = 0;
            for (int k = p1; k < p1 + kernel_size; k++) {
                for (int l = p2; l < p2 + kernel_size; l++) {
                    output[i * o2 + j] += input[k * n + l] * kernel[row * kernel_size + col];
                    col++;
                }
                col = 0;
                row++;
            }
            col = 0;
            row = 0;
        p2 += stride;
        }
    p2 = 0;
    p1 += stride;   
    }
    p1 = 0;
    p2 = 0;
}

// m,n是输出矩阵的大小
// padding是填充大小
// k为原始矩阵列数
void padding(int padding, float *input, int k, float *output, int m, int n) {
    if (padding <= 0){
        cout << "padding must be greater than 0!" << endl;
    }else {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if((i >= padding) && (i < m - padding) && (j >= padding) && (j < n - padding)) {
                    output[i * n + j] = input[(i - padding) * k + (j - padding)];
                }else{
                    output[i * n + j] = 0;
                }
            }
        }
    }
}

// 矩阵旋转180度
void sgrt(float *input, float *output, int m, int n) {
    int size = m * n;
    for (int i = 0; i < size; i++) {
        output[i] = input[size - 1 - i];
    }
}

// 反向传播
// 对卷积核的求梯度
void back_g(float *grad, int grad_size, float *input, int a, int b, int stride, float *output) {
    finke(input, output, a, b, grad_size, 0, stride, grad);
}

// 上一层的梯度
void back_s(float *grad, int grad_size, float *kernel, int kernel_size, int stride, float *output) {
    float *temp = new float[kernel_size * kernel_size];// 旋转后的卷积核
    sgrt(kernel, temp, kernel_size, kernel_size);
    int t = grad_size + kernel_size - 1;
    float *temp2 = new float[t * t];// 填充后的grad
    padding(kernel_size-1,grad, grad_size, temp2, t, t);
    finke(temp2, output, t, t, kernel_size, 0, stride, temp);
}

int main() {
    float ker[4] = {1, 2, 3, 4};
    float input[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    float output[4 * 4] = {0};
    // finke(input, output, 3, 3, 2, 0, 1, ker);
    // for (int i = 0; i < 4; i++) {
    //     cout << output[i] << endl;
    // }
    padding(1, ker, 2, output, 4, 4);
    
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            cout << output[i * 4 + j] << " ";
        }
        cout << endl;
    }
    return 0;
}